﻿using ARchGL.Declaration.Platform.Domain.Entities;
using ARchGL.Declaration.Platform.Domain.Events;
using ARchGL.Declaration.Platform.Service.Dtos;
using ARchGL.Declaration.Platform.Service.EventHandles;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Web;
using TDF.Core.Configuration;
using TDF.Core.Exceptions;
using TDF.Core.Ioc;
using TDF.Core.Models;
using TDF.Data.Repository;
using TDF.Web.Models;

namespace ARchGL.Declaration.Platform.Service
{
    /// <summary>
    /// 项目服务
    /// </summary>
    public partial class ProjectService : BaseService, IProjectService
    {
        #region 项目

        ///获取项目-分页数据集合
        public IPagedList<ProjectDto> GetProjectPagedList(ProjectCriteria criteria)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase<DP_Project>>())
            {
                return repository.IQueryable()
                    .WhereByKeywords(criteria?.Keywords?.Trim())
                    .WhereByType(criteria.Type)
                    .WhereByChangeType(ChangeType.正常)
                    .WhereBySoftDeletedStatus(SoftDeletedStatus.正常)
                    .WhereByBuilderUnitId(criteria.BuilderUnitId)
                    .WhereByParentId(criteria.ParentId)
                    .WhereByParentIdList(criteria.ParentIdList)
                    .WhereByAuditId(criteria.AuditId)
                    .WhereByAreaId(criteria.AreaId)
                    .WhereByCodeList(criteria.CodeList)
                    .WhereByAuditIdList(criteria.AuditIdList)
                    .ToDto()
                    .OrderByDescending(x => x.CreatedTime)
                    .ToPageResult1(criteria.PageIndex, criteria.PageSize);
            }
        }

        ///获取项目下的工程数量
        public int GetProjectChildCountId(Guid id)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase<DP_Project>>())
            {
                var query = repository.IQueryable(x => x.ParentId == id).Select(x => x.Id);
                return query.Count();
            }
        }

        ///根据项目编码获取项目信息
        public ProjectDto GetProjectByCode(string code, bool isChildParject = false)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase<DP_Project>>())
            {
                var entity = repository.FindEntity(x => x.Code == code && x.ParentId == Guid.Empty);
                return entity.Merge<DP_Project, ProjectDto>();
            }
        }

        ///根据项目Id获取项目信息
        public ProjectDto GetProjectById(Guid id)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase<DP_Project>>())
            {
                var entity = repository.FindEntity(id);
                if (entity.IsNull()) throw new KnownException("项目不存在");
                return entity.Merge<DP_Project, ProjectDto>();
            }
        }

        ///获取项目下最大工程编码
        public ProjectDto GetProjectMaxChildCode(Guid id)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase<DP_Project>>())
            {
                var entity = repository.IQueryable().WhereByParentId(id)
                    .OrderByDescending(x => x.CreatedTime)
                    .ThenByDescending(x => x.ChildCode)
                    .ToDto().FirstOrDefault();

                return entity;
            }
        }

        ///获取项目下 一级分类 与 二级分类 概况（分类为主）
        public IPagedList<ProjectCategoryFirstCategoryOverviewDto> GetProjectCategoryFirstCategoryOverview(ProjectOverviewCriteria criteria)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase>())
            {
                var project = repository.FindEntity<DP_Project>(criteria.ProjectId);
                if (project.IsNull()) throw new KnownException("项目不存在");

                var overviewList = new PagedList<ProjectCategoryFirstCategoryOverviewDto>();//概况信息

                var projectFileList = GetProjectFileList(new ProjectFileCriteria { ProjectId = criteria.ProjectId }, repository);//获取项目文件

                var firstProjectCategoryList = GetAllProjectCategoryPagedList().Rows.Where(x => x.ParentId == Guid.Empty && x.Type == project.Type).ToList();//一级分类

                var projectReviewHistoryDict = GetProjectReviewHistoryGroupByFirstCategoryIdList(new ProjectReviewHistoryCriteria { ProjectId = criteria.ProjectId });//一级分类最后审核记录

                foreach (var item in firstProjectCategoryList)
                {
                    var overview = new ProjectCategoryFirstCategoryOverviewDto
                    {
                        Id = item.Id,
                        ParentId = item.ParentId,
                        Name = item.Name,
                        Sort = item.Sort,
                    };

                    //获取二级分类下的所有文件并计算上传总数
                    var secondProjectCategoryList = allCategoryListCache.Rows.Where(x => x.ParentId == item.Id).ToList();
                    overview.SecondCategoryCount1 = projectFileList.Where(x => x.SecondCategoryId == secondProjectCategoryList[0].Id).Count();//质量验收记录
                    overview.SecondCategoryCount2 = projectFileList.Where(x => x.SecondCategoryId == secondProjectCategoryList[1].Id).Count();//质量控制资料核查记录
                    overview.SecondCategoryCount3 = projectFileList.Where(x => x.SecondCategoryId == secondProjectCategoryList[2].Id).Count();//安全和功能检验资料核查和主要功能抽查记录

                    if (secondProjectCategoryList.Count > 3)//建筑节能 中没有 观感质量检查记录
                        overview.SecondCategoryCount4 = projectFileList.Where(x => x.SecondCategoryId == secondProjectCategoryList[3].Id).Count();//观感质量检查记录

                    if (secondProjectCategoryList.Count > 4)
                        overview.SecondCategoryCount5 = projectFileList.Where(x => x.SecondCategoryId == secondProjectCategoryList[4].Id).Count();

                    if (secondProjectCategoryList.Count > 5)
                        overview.SecondCategoryCount5 = projectFileList.Where(x => x.SecondCategoryId == secondProjectCategoryList[5].Id).Count();

                    if (secondProjectCategoryList.Count > 6)
                        overview.SecondCategoryCount5 = projectFileList.Where(x => x.SecondCategoryId == secondProjectCategoryList[6].Id).Count();

                    if (secondProjectCategoryList.Count > 7)
                        overview.SecondCategoryCount5 = projectFileList.Where(x => x.SecondCategoryId == secondProjectCategoryList[7].Id).Count();

                    if (secondProjectCategoryList.Count > 8)
                        overview.SecondCategoryCount5 = projectFileList.Where(x => x.SecondCategoryId == secondProjectCategoryList[8].Id).Count();


                    //审核状态信息赋值
                    var xc = GetProjectReviewHistoryFirstCategoryId(projectReviewHistoryDict, item.Id, criteria.ProjectId);

                    var projectReviewHistory = GetProjectReviewHistory(projectReviewHistoryDict, item.Id, criteria.ProjectId);
                    overview.Status = projectReviewHistory != null ? projectReviewHistory.Status : AuditStatus.未报审;
                    overview.OperatorName = projectReviewHistory?.OperatorName;
                    overview.Position = projectReviewHistory?.Position;
                    overview.Telephone = projectReviewHistory?.Telephone;

                    if (projectReviewHistory != null)
                    {
                        overview.AuditName = projectReviewHistory?.AuditName;
                        overview.AuditTime = projectReviewHistory.AuditTime;
                        overview.SubmitTime = projectReviewHistory.SubmitTime;
                        overview.OperatorName = projectReviewHistory.OperatorName;
                        overview.Position = projectReviewHistory.Position;
                        overview.Telephone = projectReviewHistory.Telephone;
                        overview.Remark = projectReviewHistory.Remark;
                        overview.CreatedTime = projectReviewHistory.CreatedTime;
                    }

                    overviewList.Rows.Add(overview);
                }

                return overviewList;
            }
        }

        ///获取项目下 一级分类概况（工程为主）
        public IPagedList<ProjectFirstCategoryOverviewDto> GetProjectFirstCategoryOverview(ProjectOverviewCriteria criteria)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase>())
            {
                var projectList = repository.IQueryable<DP_Project>()//获取项目信息
                    .WhereByKeywords(criteria?.Keywords?.Trim())
                    .WhereByType(criteria.Type)
                    .WhereByChildCode(criteria.ChildCode)
                    .WhereByChangeType(criteria.ChangeType)
                    .WhereByIsChildParject(criteria.IsChildProject)
                    .WhereByIdList(criteria.ProjectIdList)
                    .WhereByParentId(criteria.ParentId)
                    .WhereByAuditId(criteria.AuditId)
                    .WhereByAreaId(criteria.AreaId)
                    .WhereByBuilderUnitId(criteria.BuilderUnitId)
                    .ToDto()
                    .OrderByDescending(x => x.Status).ThenBy(x => x.AuditTime)
                    .ToPageResult1(criteria.PageIndex, criteria.PageSize);

                var projectCategoryList = GetAllProjectCategoryPagedList().Rows//获取一级分类信息
                    .Where(x => x.ParentId == Guid.Empty)
                    .OrderBy(x => x.Sort).ToList();

                var overviewList = AssembleOverview(projectList, projectCategoryList, repository);//数据组装

                #region Backup code
                //var reviewingList = new List<ProjectFirstCategoryOverviewDto>();
                //var otherList = new List<ProjectFirstCategoryOverviewDto>();
                //var index = 0;
                ////数据再排序     
                //foreach (var item in overviewList.Rows)
                //{
                //    if (reviewingList.Count != 0) index = reviewingList.Count - 1;

                //    if (item.FirstCategoryStatus1 == AuditStatus.待审核 || item.FirstCategoryStatus2 == AuditStatus.待审核 ||
                //        item.FirstCategoryStatus3 == AuditStatus.待审核 || item.FirstCategoryStatus4 == AuditStatus.待审核)
                //        reviewingList.Insert(index, item);
                //    else otherList.Add(item);
                //}

                //overviewList.Rows = new List<ProjectFirstCategoryOverviewDto>();
                //overviewList.Rows.AddRange(reviewingList);
                //overviewList.Rows.AddRange(otherList);
                #endregion

                overviewList.TotalPages = projectList.TotalPages;
                overviewList.TotalCount = projectList.TotalCount;
                overviewList.PageIndex = criteria.PageIndex;
                overviewList.PageSize = projectList.PageSize;
                return overviewList;
            }
        }

        ///数据组装
        private PagedList<ProjectFirstCategoryOverviewDto> AssembleOverview(PagedList<ProjectDto> projectList, List<ProjectCategoryDto> projectCategoryList, IRepositoryBase repository)
        {
            var overviewList = new PagedList<ProjectFirstCategoryOverviewDto>();//概况信息

            //项目 Id 集合赋值
            var projectFileCriteria = new ProjectFileCriteria { ProjectIdList = new List<Guid>() };
            var parentIdList = projectList.Rows.Select(x => x.ParentId.Value).ToList();
            foreach (var item in projectList.Rows)
            {
                projectFileCriteria.ProjectIdList.Add(item.Id);
            }

            var parentProjectList = repository.IQueryable<DP_Project>().WhereByIdList(parentIdList).ToList();//工程对应父级项目
            var projectFileList = GetProjectFileList(projectFileCriteria, repository);//获取项目文件

            var projectReviewHistoryDict = GetProjectReviewHistoryGroupByFirstCategoryIdList(new ProjectReviewHistoryCriteria { ProjectIdList = projectFileCriteria.ProjectIdList });//一级分类最后审核记录

            foreach (var item in projectList.Rows)
            {
                var overview = new ProjectFirstCategoryOverviewDto
                {
                    Id = item.Id,//项目 Id
                    Name = item.Name,
                    Code = item.Code,
                    ChildCode = item.ChildCode,
                    BuilderUnitNames = item.BuilderUnitNames,
                    BuilderUnitIds = item.BuilderUnitIds,
                    AuditId = item.AuditId,
                    AuditName = item.AuditName,
                    IsBIM = item.IsBIM,
                    Location = item.Location,
                    Area = item.Area,
                    Type = item.Type,
                    Status = item.Status,
                    CreatedTime = item.CreatedTime,
                };

                //获取各级分类下的所有文件并计算上传总数
                var currentProjectFileList = projectFileList.Where(x => x.ProjectId == item.Id);

                overview.FileCount = currentProjectFileList.Count();
                overview.ProjectName = parentProjectList.FirstOrDefault(x => x.Id == item.ParentId).Name;

                ////文件数赋值
                //overview.FirstCategoryCount1 = currentProjectFileList.Count(x => x.FirstCategoryId == projectCategoryList[0].Id);//地基与基础
                //overview.FirstCategoryCount2 = currentProjectFileList.Count(x => x.FirstCategoryId == projectCategoryList[1].Id);//主体结构
                //overview.FirstCategoryCount3 = currentProjectFileList.Count(x => x.FirstCategoryId == projectCategoryList[2].Id);//建筑节能
                //overview.FirstCategoryCount4 = currentProjectFileList.Count(x => x.FirstCategoryId == projectCategoryList[3].Id);//竣工验收

                //一级分类 审核状态 赋值
                overview.FirstCategoryStatus1 = GetProjectReviewHistoryFirstCategoryId(projectReviewHistoryDict, projectCategoryList[0].Id, item.Id);
                overview.FirstCategoryStatus2 = GetProjectReviewHistoryFirstCategoryId(projectReviewHistoryDict, projectCategoryList[1].Id, item.Id);
                overview.FirstCategoryStatus3 = GetProjectReviewHistoryFirstCategoryId(projectReviewHistoryDict, projectCategoryList[2].Id, item.Id);
                overview.FirstCategoryStatus4 = GetProjectReviewHistoryFirstCategoryId(projectReviewHistoryDict, projectCategoryList[3].Id, item.Id);
                //overview.AuditTime = item.AuditTime;

                overview.WaitReviewStatusCount = GetProjectReviewHistoryFirstCategoryId(projectReviewHistoryDict, projectCategoryList, 6, item.Id);
                overview.FirstCategoryStatus = GetProjectReviewHistoryFirstCategoryId(projectReviewHistoryDict, projectCategoryList, 6, item.Id, AuditStatus.已完成) + "/" + projectCategoryList.Count;

                overviewList.Rows.Add(overview);
            }
            return overviewList;
        }

        ///创建项目并同步创建项目帐号
        private Guid CreateProject(ProjectDto dto)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase>().BeginTrans())
            {
                var auditAccount = repository.FindEntity<Account>(dto.AuditId);
                if (auditAccount.IsNull()) throw new KnownException("质监员不存在，请重新输入");

                var enterpriseAccount = new Account();
                var childCode = dto.Code;

                var project = new DP_Project();
                var projectChild = new DP_Project();
                var projectQuery = repository.IQueryable<DP_Project>();
                if (dto.ParentId.HasValue)
                {//检查工程是否存在
                    project = projectQuery.Where(x => x.Id == dto.ParentId).FirstOrDefault();
                    var query = projectQuery.Where(x => x.ParentId == dto.ParentId && x.ChildCode == dto.ChildCode.Trim() && x.ChangeType == ChangeType.正常);
                    if (!query.FirstOrDefault().IsNull()) throw new KnownException($"编号[{dto.ChildCode.Trim()}]已存在，请重新输入");

                    childCode = dto.ChildCode;
                }
                else
                {//检查项目是否存在
                    project = projectQuery.Where(x => x.Code == dto.Code.Trim()).WhereBySoftDeletedStatus(SoftDeletedStatus.正常).FirstOrDefault();
                    childCode = "000";

                    enterpriseAccount = repository.FindEntity<Account>(Guid.Parse(dto.BuilderUnitIds));
                    if (enterpriseAccount.IsNull()) throw new KnownException("企业不存在，请重新输入");
                }

                //if (!project.IsNull()) throw new KnownException("项目已存在，请重新输入");

                //获取当前项目对应的项目帐号
                var projectAccount = repository.FindEntity<Account>(x => x.Type == AccountType.项目帐号 && x.Number == dto.Code.Trim());

                if (project.IsNull())
                {//项目不存在，创建项目
                    project = dto.Merge<ProjectDto, DP_Project>();
                    //project.Id = Guid.NewGuid();项目Id在申请创建时生成
                    project.ParentId = Guid.Empty;
                    //project.Area = CurrentSession.AccountName;
                    //project.AreaId = CurrentSession.AccountId;
                    project.BuilderUnitNames = enterpriseAccount.Name;
                    project.BuilderUnitIds = enterpriseAccount.Id.ToString();
                    project.Status = AuditStatus.未报审;
                    project.ChangeType = ChangeType.正常;
                    project.SoftDeleted = SoftDeletedStatus.正常;
                    project.AuditId = auditAccount.Id;
                    project.AuditName = auditAccount.Name;
                    project.CreatedTime = DateTime.Now;
                    repository.Insert(project);//创建项目

                    if (projectAccount.IsNull())
                    {//项目帐号不存在，创建与项目关联的项目帐号
                        projectAccount = new Account
                        {
                            Id = Guid.NewGuid(),
                            Name = project.Name,
                            Number = project.Code,
                            Password = project.Code.ToMD5(),
                            Type = AccountType.项目帐号,
                            AccountIds = project.AuditId.ToString(),//关联审核人与项目帐号
                            Status = 1,
                            CreatedTime = project.CreatedTime,
                        };
                        repository.Insert(projectAccount);
                    }
                    else
                    {//项目帐号已存在，新增审核帐号 与 项目帐号关联
                        var accountIds = projectAccount.AccountIds.Split(",").ToList();
                        if (accountIds == null) accountIds = new List<string>();
                        if (!accountIds.Contains(CurrentSession.AccountId.ToString()))
                        {
                            accountIds.Add(project.AuditId.ToString());
                            projectAccount.AccountIds = string.Join(",", accountIds);
                            repository.Update(projectAccount);
                        }
                    }

                    {//关联项目与企业
                        var accountIds = enterpriseAccount.AccountIds.Split(",").ToList();
                        if (accountIds == null) accountIds = new List<string>();
                        if (!accountIds.Contains(CurrentSession.AccountId.ToString()))
                        {
                            accountIds.Add(project.AuditId.ToString());
                            enterpriseAccount.AccountIds = string.Join(",", accountIds);
                            repository.Update(enterpriseAccount);
                        }
                    }
                }

                #region 2.0 开始创建项目时，不自动创建工程
                //projectChild = project.Merge<DP_Project, DP_Project>();
                //projectChild.ParentId = project.Id;//先将父级Id赋值
                //projectChild.Id = Guid.NewGuid();//再换一个新Id
                //projectChild.Name = dto.Name;
                //projectChild.Code = project.Code;
                //projectChild.ChildCode = childCode;
                //projectChild.CreatedTime = DateTime.Now;
                //repository.Insert(projectChild);//创建工程
                #endregion

                repository.Commit();
                return project.Id;
            }
        }

        ///删除项目
        public void RemoveProject(DP_Project entity, IRepositoryBase repository)
        {
            if (entity.IsNull()) throw new KnownException("项目不存在");

            var projectList = repository.IQueryable<DP_Project>().Where(x => x.Code == entity.Code).ToList();
            foreach (var item in projectList)
            {
                var project = repository.FindEntity<DP_Project>(item.Id);
                project.SoftDeleted = SoftDeletedStatus.删除;
                repository.Update(project);
            }
        }

        ///编辑项目
        public void ModifyProject(ProjectDto dto)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase>())
            {
                var project = repository.FindEntity<DP_Project>(dto.Id);
                if (project.IsNull()) throw new KnownException("项目不存在");

                //project.ConstructionUnit = dto.ConstructionUnit;
                ////entity.ConstructionUnitId = dto.ConstructionUnitId;
                ////entity.BuilderUnitNames = dto.BuilderUnitNames;
                ////entity.BuilderUnitIds = dto.BuilderUnitIds;
                //project.SupervisionUnit = dto.SupervisionUnit;
                ////entity.SupervisionUnitId = dto.SupervisionUnitId;
                //project.TestingUnit = dto.TestingUnit;
                ////entity.TestingUnitId = dto.TestingUnitId;
                //project.PremixedSupplier = dto.PremixedSupplier;
                ////entity.PremixedSupplierId = dto.PremixedSupplierId;
                //project.DesignUnit = dto.DesignUnit;
                ////entity.DesignUnitId = dto.DesignUnitId;
                //project.SurveyUnit = dto.SurveyUnit;
                ////entity.SurveyUnitId = dto.SurveyUnitId;

                InitUnitInfo(dto, project);//项目信息赋值                               
                repository.Update(project);//更新项目信息

                //更新项目下的第一个工程信息
                var childProject = repository.FindEntity<DP_Project>(x => x.ParentId == project.Id && x.ChangeType == ChangeType.正常 && x.ChildCode == "000");
                if (!childProject.IsNull())
                {
                    InitUnitInfo(dto, childProject);//工程信息赋值
                    repository.Update(childProject);//更新工程信息
                }
            }
        }

        ///提交创建项目申请
        public void SubmitCreateProjectReview(ProjectReviewHistoryDto dto, Guid manageId)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase>())
            {
                var manageAccount = repository.FindEntity<Account>(manageId);//质监员
                if (manageAccount.IsNull()) throw new KnownException("质监员不存在，请重新输入");

                var entity = dto.Merge<ProjectReviewHistoryDto, DP_Project_Review_History>();
                entity.ProjectId = Guid.NewGuid();//提前生成项目Id，串通流程
                entity.Type = ReviewType.创建项目;
                entity.ModifierId = manageId;//修改人临时用于存放质监员信息，在创建项目时使用
                entity.ModifierName = manageAccount.Name;
                CreateSubmitProjectReview(entity, repository);
            }
        }

        private void CreateSubmitProjectReview(DP_Project_Review_History entity, IRepositoryBase repository)
        {
            if (CurrentSession.Type != AccountType.区县帐号)
                throw new KnownException("当前用户没有权限创建项目，请联系管理员");

            if (entity.Type != ReviewType.创建项目)
            {
                var hasNeedAuditData = repository.IQueryable<DP_Project_Review_History>(true)
                    .Any(x => x.ProjectId == entity.ProjectId && x.Status == AuditStatus.待审核);
                if (hasNeedAuditData) throw new KnownException("当前项目有待审核记录，请等待管理员审核");
            }

            var builderUnitAccount = repository.FindEntity<Account>(Guid.Parse(entity.BuilderUnitIds));//施工企业
            if (builderUnitAccount.IsNull()) throw new KnownException("施工企业不存在，请重新输入");

            var auditAccount = repository.FindEntity<Account>(x => x.Type == 0);//总站管理员

            entity.Id = Guid.NewGuid();
            entity.AuditId = auditAccount.Id;
            entity.AuditName = auditAccount.Name;
            entity.AuditTime = DateTimeHelper.MinDateTime;
            entity.Status = AuditStatus.待审核;//提交审核
            entity.CreatorId = CurrentSession.AccountId;
            entity.CreatorName = CurrentSession.AccountName;
            entity.BuilderUnitNames = builderUnitAccount.Name;
            entity.CreatedTime = DateTime.Now;
            entity.SubmitTime = DateTime.Now;//提交审核时间作为报审时间
            repository.Insert(entity);

            CreateOrUpdateOperatorHistory(entity);//创建或更新操作人
        }

        ///提交修改项目申请
        public void SubmitModifyProjectReview(ProjectReviewHistoryDto dto)
        {
            SubmitModifyOrRemoveProjectReview(dto, ReviewType.修改项目);
        }

        private void SubmitModifyOrRemoveProjectReview(ProjectReviewHistoryDto dto, ReviewType type)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase>())
            {
                var project = repository.FindEntity<DP_Project>(dto.ProjectId);
                if (project.IsNull()) throw new KnownException("项目不存在，请重新输入");

                var entity = dto.Merge<ProjectReviewHistoryDto, DP_Project_Review_History>();
                entity.Type = type;
                entity.ModifierId = project.AuditId;//质监员赋值
                entity.ModifierName = project.AuditName;
                CreateSubmitProjectReview(entity, repository);
            }
        }

        ///提交删除项目申请
        public void SubmitRemoveProjectReview(ProjectReviewHistoryDto dto)
        {
            SubmitModifyOrRemoveProjectReview(dto, ReviewType.删除项目);
        }

        ///初始化单位信息
        public void InitUnitInfo(ProjectDto dto, DP_Project project)
        {
            project.ConstructionUnit = dto.ConstructionUnit;
            //entity.ConstructionUnitId = dto.ConstructionUnitId;
            //entity.BuilderUnitNames = dto.BuilderUnitNames;
            //entity.BuilderUnitIds = dto.BuilderUnitIds;
            project.SupervisionUnit = dto.SupervisionUnit;
            //entity.SupervisionUnitId = dto.SupervisionUnitId;
            project.TestingUnit = dto.TestingUnit;
            //entity.TestingUnitId = dto.TestingUnitId;
            project.PremixedSupplier = dto.PremixedSupplier;
            //entity.PremixedSupplierId = dto.PremixedSupplierId;
            project.DesignUnit = dto.DesignUnit;
            //entity.DesignUnitId = dto.DesignUnitId;
            project.SurveyUnit = dto.SurveyUnit;
            //entity.SurveyUnitId = dto.SurveyUnitId;

            if (!string.IsNullOrWhiteSpace(dto.Name)) project.Name = dto.Name;
            if (!string.IsNullOrWhiteSpace(dto.Address)) project.Address = dto.Address;
            if (!string.IsNullOrWhiteSpace(dto.Location)) project.Location = dto.Location;
            if (!string.IsNullOrWhiteSpace(dto.Image)) project.Image = dto.Image;
        }

        ///修改项目/工程名称
        public bool ChangeProjectName(Guid projectId, string name)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase<DP_Project>>())
            {
                var entity = repository.FindEntity(projectId);
                if (entity.IsNull()) throw new KnownException("项目不存在");

                entity.Name = name.Trim();

                return repository.Update(entity) > 0;
            }
        }

        ///修改工程编号
        public bool ChangeProjectChildCode(Guid projectId, string childCode)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase<DP_Project>>())
            {
                if (CurrentSession.Type != AccountType.项目帐号) throw new KnownException("当前帐号没有修改权限，请联系项目方修改");

                var entity = repository.FindEntity(projectId);
                if (entity.IsNull()) throw new KnownException("工程不存在");

                if (repository.IQueryable().Any(x => x.ParentId == entity.ParentId && x.ChangeType == ChangeType.正常 && x.ChildCode == childCode))
                    throw new KnownException("编号已存在，请重新输入");

                entity.ChildCode = childCode.Trim();

                return repository.Update(entity) > 0;
            }
        }

        ///上传项目设计图片
        [Obsolete("对接文件服务后，该方法不再使用")]
        public string ProjectUploadImage(Guid id)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase>())
            {
                var entity = repository.FindEntity<DP_Project>(id);
                if (entity.IsNull()) throw new KnownException("项目不存在");

                #region 处理上传图片

                var configs = new Configs();
                //根据项目id创建对应的文件夹
                var path = configs.GetValue("ImagePath") + "/" + id;
                if (!Directory.Exists(path)) Directory.CreateDirectory(path);

                var fileName = entity.Id.ToString();//用项目Id作为展示图片的文件名
                var filePath = "/" + id;

                var request = HttpContext.Current.Request;
                if (!request.Files.AllKeys.Any() && request.Files.Count <= 0)
                    throw new KnownException("请选择上传文件 ");

                var file = HttpContext.Current.Request.Files[0];

                //截取文件后缀名
                var extension = file.FileName.Substring(file.FileName.LastIndexOf("."));
                if (ExtensionList.Contains(extension)) throw new KnownException("不允许上传该类文件 " + file.FileName);

                fileName = fileName + "-COVER" + extension;

                var contentLength = Convert.ToInt32(configs.GetValue("FileMaxLength"));
                if (file.ContentLength > contentLength) throw new KnownException("上传文件超出限制大小 ");

                //保存文件操作
                file.SaveAs(path + "/" + fileName);

                //返回文件相对路径
                entity.Image = "/ProjectImage" + filePath + "/" + fileName;

                #endregion

                entity.ImageUploadTime = DateTime.Now;//更新图片上传时间
                repository.Update(entity);

                return entity.Image;
            }
        }

        ///保存项目设计图
        public void ProjectSaveUploadImage(Guid id, string path)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase>())
            {
                var entity = repository.FindEntity<DP_Project>(id);
                if (entity.IsNull()) throw new KnownException("项目不存在");

                entity.Image = path;
                entity.ImageUploadTime = DateTime.Now;//更新图片上传时间

                repository.Update(entity);
            }
        }

        ///检查工程一级分类最后审核状态
        public bool CheckProjectFirstCategoryStatus(Guid projectId)
        {
            var fList = GetProjectFirstCategoryOverview(new ProjectOverviewCriteria
            {
                PageIndex = 1,
                PageSize = 10,
                ProjectIdList = new List<Guid> { projectId },
                IsChildProject = true,
                ChangeType = ChangeType.正常
            }).Rows;

            var f = fList.Where(x => x.Id == projectId).FirstOrDefault();
            if (!f.IsNull())
            {
                if (f.FirstCategoryStatus1 == AuditStatus.待审核 ||
                    f.FirstCategoryStatus2 == AuditStatus.待审核 ||
                    f.FirstCategoryStatus3 == AuditStatus.待审核 ||
                    f.FirstCategoryStatus4 == AuditStatus.待审核 ||

                    f.FirstCategoryStatus1 == AuditStatus.已完成 ||
                    f.FirstCategoryStatus2 == AuditStatus.已完成 ||
                    f.FirstCategoryStatus3 == AuditStatus.已完成 ||
                    f.FirstCategoryStatus4 == AuditStatus.已完成)
                    return false;
            }
            return true;
        }

        #endregion

        #region 项目分类

        ///所有分类缓存
        private static IPagedList<ProjectCategoryDto> allCategoryListCache = null;

        ///初始化分类数据
        public void InitProjectCategory(List<DP_Project_Category> list)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase>().BeginTrans())
            {
                foreach (var item in list) repository.Insert(item);
                repository.Commit();
            }
        }

        ///获取所有项目分类
        private IPagedList<ProjectCategoryDto> GetAllProjectCategoryPagedList()
        {
            if (allCategoryListCache != null) return allCategoryListCache;

            using (var repository = Ioc.Resolve<IRepositoryBase>())
            {
                return allCategoryListCache = repository.IQueryable<DP_Project_Category>()
                    .ToDto()
                    .OrderBy(x => x.Sort)
                    .ToPageResult1(1, 1000);
            }
        }

        ///根据分类获取二级分类集合
        public List<ProjectCategoryDto> GetProjectCategoryByType(int type)
        {
            var result = GetAllProjectCategoryPagedList().Rows.Where(x => x.Type == type && x.Level == 2).OrderBy(x => x.Sort);
            if (type == 1)
            {//当前数据结构，只有类型为【1.房屋建筑工程】的数据需要特殊处理
                var list = new List<ProjectCategoryDto>();
                foreach (var item in result)
                {
                    if (!list.Any(x => x.Name == item.Name))
                        list.Add(item);
                }
                return list;
            }
            return result.ToList();
        }

        ///获取项目分类-分页数据集合
        public IPagedList<ProjectCategoryDto> GetProjectCategoryPagedList(ProjectCategoryCriteria criteria, IRepositoryBase repository = null)
        {
            if (repository == null) repository = Ioc.Resolve<IRepositoryBase>();
            using (repository)
            {
                return repository.IQueryable<DP_Project_Category>()
                    .WhereByKeywords(criteria?.Keywords?.Trim())
                    .WhereByType(criteria.Type)
                    .WhereByParentId(criteria.ParentId)
                    .WhereByLevel(criteria.Level)
                    .ToDto()
                    .OrderBy(x => x.Sort)
                    .ToPageResult1(criteria.PageIndex, criteria.PageSize);
            }
        }

        ///获取项目分类，根据 父级 Id
        public ProjectCategoryDto GetProjectCategoryByParentId(Guid parentId, IRepositoryBase repository = null)
        {
            if (repository == null) repository = Ioc.Resolve<IRepositoryBase>();
            using (repository)
            {
                var entity = repository.FindEntity<DP_Project_Category>(x => x.ParentId == parentId);
                return entity.Merge<DP_Project_Category, ProjectCategoryDto>();
            }
        }

        ///获取项目分类，根据 Id
        public ProjectCategoryDto GetProjectCategoryById(Guid id, IRepositoryBase repository = null)
        {
            if (repository == null) repository = Ioc.Resolve<IRepositoryBase>();
            using (repository)
            {
                var entity = repository.FindEntity<DP_Project_Category>(id);
                return entity.Merge<DP_Project_Category, ProjectCategoryDto>();
            }
        }

        ///获取项目分类，根据 父级 Id
        public ProjectCategoryDto GetProjectCategoryByParentId(List<ProjectCategoryDto> list, Guid parentId)
        {
            return list.FirstOrDefault(x => x.ParentId == parentId);
        }

        ///获取项目分类，根据 子级编号
        public ProjectCategoryDto GetProjectCategoryByLevel(int level)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase<DP_Project_Category>>())
            {
                var entity = repository.FindEntity(x => x.Level == level);
                return AutoMapper.Mapper.Map<ProjectCategoryDto>(entity);
            }
        }

        ///获取项目分类，根据 子级编号
        public ProjectCategoryDto GetProjectCategoryByLevel(List<ProjectCategoryDto> list, int level)
        {
            return list.FirstOrDefault(x => x.Level == level);
        }

        #endregion

        #region 项目文件

        ///获取项目文件-分页数据集合
        public IPagedList<ProjectFileDto> GetProjectFilePagedList(ProjectFileCriteria criteria, IRepositoryBase repository = null)
        {
            if (repository == null) repository = Ioc.Resolve<IRepositoryBase>();
            using (repository)
            {
                return repository.IQueryable<DP_Project_File>()
                    .WhereByStatus(criteria.Status)
                    .WhereBySoftDeletedStatus(SoftDeletedStatus.正常)
                    .WhereByKeywords(criteria?.Keywords?.Trim())
                    .WhereByFirstCategoryId(criteria.FirstCategoryId)
                    .WhereBySecondCategoryId(criteria.SecondCategoryId)
                    .WhereByThreeCategoryId(criteria.ThreeCategoryId)
                    .WhereByProjectId(criteria.ProjectId)
                    .WhereByProjectIdList(criteria.ProjectIdList)
                    .ToDto()
                    .OrderByDescending(x => x.CreatedTime)
                    .ToPageResult1(criteria.PageIndex, criteria.PageSize);
            }
        }

        ///获取项目文件-数据集合
        public List<ProjectFileDto> GetProjectFileList(ProjectFileCriteria criteria, IRepositoryBase repository = null)
        {
            if (repository == null) repository = Ioc.Resolve<IRepositoryBase>();
            using (repository)
            {
                return repository.IQueryable<DP_Project_File>()
                    .WhereByStatus(criteria.Status)
                    .WhereBySoftDeletedStatus(SoftDeletedStatus.正常)
                    .WhereByKeywords(criteria?.Keywords?.Trim())
                    .WhereByFirstCategoryId(criteria.FirstCategoryId)
                    .WhereBySecondCategoryId(criteria.SecondCategoryId)
                    .WhereByThreeCategoryId(criteria.ThreeCategoryId)
                    .WhereByProjectId(criteria.ProjectId)
                    .WhereByProjectIdList(criteria.ProjectIdList)
                    .WhereByProjectIdList(criteria.ProjectIdList)
                    .ToDto()
                    .OrderByDescending(x => x.CreatedTime).ToList();
            }
        }

        /// 创建项目文件
        public Guid CreateProjectFile(ProjectFileDto dto)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase>())
            {
                //获取所有分类
                var allCategoryList = GetAllProjectCategoryPagedList().Rows.ToList();

                var fourCategory = allCategoryList.FirstOrDefault(x => x.ParentId == dto.ThreeCategoryId);
                if (fourCategory.IsNull()) throw new KnownException("分类不存在");

                var threeCategory = allCategoryList.FirstOrDefault(x => x.Id == fourCategory.ParentId); ;
                if (threeCategory.IsNull()) throw new KnownException("分类不存在");

                var secondCategory = allCategoryList.FirstOrDefault(x => x.Id == threeCategory.ParentId);
                if (secondCategory.IsNull()) throw new KnownException("分类不存在");

                var firstCategory = allCategoryList.FirstOrDefault(x => x.Id == secondCategory.ParentId);
                if (firstCategory.IsNull()) throw new KnownException("分类不存在");

                var entity = dto.Merge<ProjectFileDto, DP_Project_File>();
                entity.Id = Guid.NewGuid();

                entity.ShortName = threeCategory?.Name;//三级分类名称
                                                       //entity.Name = fourCategory?.Name;//四级分类名称

                entity.FirstCategoryId = firstCategory.Id;
                entity.SecondCategoryId = secondCategory.Id;
                entity.SoftDeleted = SoftDeletedStatus.正常;
                entity.UploadTime = DateTime.Now;
                entity.CreatorId = CurrentSession.AccountId;
                entity.CreatorName = CurrentSession.AccountName;
                entity.CreatedTime = DateTime.Now;
                repository.Insert(entity);

                PushProjectFile(entity, firstCategory, secondCategory, threeCategory.Name, fourCategory.Name);//推送项目文件

                return entity.Id;
            }
        }

        ///过滤后缀名
        public List<string> ExtensionList = new List<string> { ".exe", ".bat", ".dll" };

        ///上传项目文件
        [Obsolete("对接文件服务后，该方法不再适用，请使用 CreateProjectFile() ")]
        public ProjectFileDto ProjectUploadFile(Guid projectId, Guid threeCategoryId)
        {
            ProjectFileDto dto = new ProjectFileDto();
            Configs configs = new Configs();
            //根据项目id创建对应的文件夹
            string path = configs.GetValue("FilePath") + "/" + projectId;
            if (!Directory.Exists(path)) Directory.CreateDirectory(path);

            var FileName = DateTime.Now.ToString("yyyyMMddHHmmss");
            var FilePath = "/" + projectId;

            var request = HttpContext.Current.Request;
            if (!request.Files.AllKeys.Any() && request.Files.Count <= 0)
                throw new KnownException("请选择上传文件 ");

            var file = HttpContext.Current.Request.Files[0];
            FileName = FileName + "-" + file.FileName;
            //截取文件后缀名
            dto.Extension = file.FileName.Substring(file.FileName.LastIndexOf("."));
            if (ExtensionList.Contains(dto.Extension)) throw new KnownException("不允许上传该类文件 " + file.FileName);

            var contentLength = Convert.ToInt32(configs.GetValue("FileMaxLength"));
            if (file.ContentLength > contentLength) throw new KnownException("上传文件超出限制大小 ");

            dto.Size = file.ContentLength / 1024;

            //保存文件操作
            file.SaveAs(path + "/" + FileName);
            //返回文件相对路径
            dto.Path = "/ProjectFile" + FilePath + "/" + FileName;
            return dto;
        }

        ///删除项目文件
        public bool DeleteFile(Guid id)
        {
            var configs = new Configs();
            //查询项目文件保存位置
            var path = configs.GetValue("FilePath").Replace(@"\ProjectFile", "");

            using (var repository = Ioc.Resolve<IRepositoryBase>())
            {
                var entity = repository.FindEntity<DP_Project_File>(id);
                if (entity.IsNull()) throw new KnownException("数据不存在，请刷新后重试");

                if (entity.CreatorId.HasValue && entity.CreatorId != Guid.Empty && // 这样判断是因为部分数据为空
                    entity.CreatorId != CurrentSession.AccountId)
                    throw new KnownException("只能删除当前账户上传的文件");

                #region 删除逻辑在文件服务中实现，这部分代码保留一段时间后删除                
                var filePath = path + "/" + entity.Path;
                //if (!File.Exists(filePath)) throw new KnownException("文件不存在，请刷新后重试");
                if (File.Exists(filePath)) File.Delete(filePath);
                #endregion

                entity.SoftDeleted = SoftDeletedStatus.删除;
                repository.Update(entity);//同时删除数据记录
            }
            return true;
        }
        #endregion

        #region 审核记录

        ///提交审核（工程）
        public void SubmitProjectReview(ProjectReviewHistoryDto dto, Guid firstCategoryId)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase>())
            {
                var project = repository.FindEntity<DP_Project>(dto.ProjectId);
                if (project.IsNull()) throw new KnownException("项目不存在");

                var firstCategory = repository.FindEntity<DP_Project_Category>(firstCategoryId);
                if (firstCategory.IsNull()) throw new KnownException("分类不存在");

                project.Status = AuditStatus.待审核;
                project.AuditTime = DateTime.Now;
                repository.Update(project);

                var frojectFileList = GetProjectFileList(new ProjectFileCriteria { ProjectId = dto.ProjectId, FirstCategoryId = firstCategoryId });//一级分类下文件数

                var projectReviewHistory = dto.Merge<ProjectReviewHistoryDto, DP_Project_Review_History>();

                projectReviewHistory.Name = project.Name;
                projectReviewHistory.Code = project.Code;
                projectReviewHistory.ChildCode = project.ChildCode;
                projectReviewHistory.BuilderUnitNames = project.BuilderUnitNames;
                projectReviewHistory.BuilderUnitIds = project.BuilderUnitIds;
                projectReviewHistory.FirstCategoryId = firstCategoryId;//一级
                projectReviewHistory.FirstCategoryName = firstCategory.Name;
                projectReviewHistory.FileCount = frojectFileList.Count;
                projectReviewHistory.AuditId = project.AuditId;
                projectReviewHistory.AuditName = project.AuditName;
                projectReviewHistory.AuditTime = DateTimeHelper.MinDateTime;
                projectReviewHistory.SubmitTime = DateTime.Now;//提交审核时间作为报审时间
                projectReviewHistory.Status = AuditStatus.待审核;//提交审核
                projectReviewHistory.Type = ReviewType.分部工程;
                projectReviewHistory.CreatorName = CurrentSession.AccountName;

                CreateProjectReviewHistory(projectReviewHistory, repository);//单条
                CreateOrUpdateOperatorHistory(projectReviewHistory);//创建或更新操作人

                PushProjectStatus(projectReviewHistory, firstCategory);//推送项目状态
            }
        }

        ///撤回审核（工程）
        public void RecallProjectReview(ProjectReviewHistoryDto dto, Guid firstCategoryId)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase>())
            {
                var project = repository.FindEntity<DP_Project>(dto.ProjectId);
                if (project.IsNull()) throw new KnownException("项目不存在");

                var firstCategory = repository.FindEntity<DP_Project_Category>(firstCategoryId);
                if (firstCategory.IsNull()) throw new KnownException("分类不存在");

                //通过项目Id和一级分类Id 获取最后的审核记录
                var projectReviewHistory = repository.IQueryable<DP_Project_Review_History>().OrderByDescending(x => x.CreatedTime).FirstOrDefault(x => x.ProjectId == dto.ProjectId && x.FirstCategoryId == firstCategoryId);

                var clone = projectReviewHistory.Clone();
                clone.AuditTime = DateTime.Now;
                repository.Update(clone);

                InsertProjectReviewHistoryInfo(projectReviewHistory, repository);
            }
        }

        private void InsertProjectReviewHistoryInfo(DP_Project_Review_History projectReviewHistory, IRepositoryBase repository)
        {
            if (projectReviewHistory.Status != AuditStatus.待审核) throw new KnownException("当前状态不能撤回");
            if (projectReviewHistory.CreatorId != CurrentSession.AccountId) throw new KnownException("只能撤回当前帐号提交的申请");

            projectReviewHistory.Id = Guid.NewGuid();
            projectReviewHistory.Status = AuditStatus.已撤回;
            projectReviewHistory.CreatedTime = DateTime.Now;
            repository.Insert(projectReviewHistory);
        }

        ///撤回 创建、修改、删除 项目审核
        public void RecallProjectReview(ProjectReviewHistoryDto dto)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase>())
            {
                var projectReviewHistory = repository.IQueryable<DP_Project_Review_History>().FirstOrDefault(x => x.Id == dto.Id);
                if (projectReviewHistory.IsNull()) throw new KnownException("审核记录不存在");

                var clone = projectReviewHistory.Clone();
                clone.AuditTime = DateTime.Now;
                repository.Update(clone);

                //通过项目Id和 获取最后的审核记录
                projectReviewHistory = repository.IQueryable<DP_Project_Review_History>().OrderByDescending(x => x.CreatedTime).FirstOrDefault(x => x.ProjectId == projectReviewHistory.ProjectId);

                InsertProjectReviewHistoryInfo(projectReviewHistory, repository);
            }
        }

        ///审核工程项目
        public void ProjectReview(ProjectReviewHistoryDto dto, bool status)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase>().BeginTrans())
            {
                var projectReviewHistory = repository.FindEntity<DP_Project_Review_History>(dto.Id);
                if (projectReviewHistory.IsNull()) throw new KnownException("审核记录不存在");

                var submitTime = DateTimeHelper.MinDateTime;
                if (projectReviewHistory?.Status == AuditStatus.待审核)
                {
                    submitTime = projectReviewHistory.SubmitTime;
                    projectReviewHistory.AuditTime = DateTime.Now;
                    repository.Update(projectReviewHistory);
                }
                else throw new KnownException("当前记录不能被审核");

                if (status)
                {
                    var project = new DP_Project();
                    if (projectReviewHistory.Type != ReviewType.创建项目)
                        project = repository.FindEntity<DP_Project>(projectReviewHistory.ProjectId);

                    if (projectReviewHistory.Type == ReviewType.修改项目)
                    {
                        project.Name = projectReviewHistory.Name;
                        project.Code = projectReviewHistory.Code;
                        project.AuditId = projectReviewHistory.ModifierId.Value;
                        project.AuditName = projectReviewHistory.ModifierName;
                        if (!project.BuilderUnitIds.Contains(","))
                        {
                            project.BuilderUnitIds = projectReviewHistory.BuilderUnitIds;
                            project.BuilderUnitNames = projectReviewHistory.BuilderUnitNames;
                        }
                        repository.Update(project);
                    }
                    else if (projectReviewHistory.Type == ReviewType.创建项目)
                    {
                        project.Id = projectReviewHistory.ProjectId;
                        project.Name = projectReviewHistory.Name;
                        project.Code = projectReviewHistory.Code;
                        project.AuditId = projectReviewHistory.ModifierId.Value;
                        project.AuditName = projectReviewHistory.ModifierName;
                        project.BuilderUnitIds = projectReviewHistory.BuilderUnitIds;
                        project.AreaId = projectReviewHistory.CreatorId.Value;
                        project.Area = projectReviewHistory.CreatorName;
                        CreateProject(project.Merge<DP_Project, ProjectDto>());
                    }
                    else if (projectReviewHistory.Type == ReviewType.删除项目)
                    {
                        if (project.AuditId != projectReviewHistory.ModifierId)
                            throw new KnownException("申请人只能删除自己账户下的项目");

                        RemoveProject(project, repository);
                    }
                }

                projectReviewHistory.Status = status ? AuditStatus.已完成 : AuditStatus.被打回;//通过 或 打回
                projectReviewHistory.AuditTime = DateTime.Now;
                projectReviewHistory.SubmitTime = submitTime;//上一次提交审核时的时间
                projectReviewHistory.OperatorName = dto.OperatorName;
                projectReviewHistory.Position = dto.Position;
                projectReviewHistory.Telephone = dto.Telephone;
                projectReviewHistory.Remark = dto.Remark;

                CreateProjectReviewHistory(projectReviewHistory.Clone(), repository);//单条
                //PushProjectStatus(projectReviewHistory, firstCategory);//推送项目状态

                CreateOrUpdateOperatorHistory(dto);//创建或更新操作人
                repository.Commit();
            }
        }

        ///审核工程
        public void ProjectReview(ProjectDto dto, Guid firstCategoryId, bool status)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase>().BeginTrans())
            {
                var account = repository.FindEntity<Account>(dto.AuditId);
                if (account.IsNull()) throw new KnownException("审核帐号不存在");

                var project = repository.FindEntity<DP_Project>(dto.Id);
                if (project.IsNull()) throw new KnownException("项目不存在");
                if (dto.AuditId != project.AuditId) throw new KnownException("当前帐号不能审核该项目");

                var firstCategory = repository.FindEntity<DP_Project_Category>(firstCategoryId);
                if (firstCategory.IsNull()) throw new KnownException("分类不存在");

                var frojectFileList = GetProjectFileList(new ProjectFileCriteria { ProjectId = dto.Id, FirstCategoryId = firstCategoryId });//一级分类下文件数

                var projectReviewHistoryList = repository.IQueryable<DP_Project_Review_History>().Where(x => x.ProjectId == project.Id && x.FirstCategoryId == firstCategoryId)
                    .Take(9).OrderByDescending(x => x.CreatedTime).ToDto().ToList();

                var submitTime = DateTimeHelper.MinDateTime;
                var entity = projectReviewHistoryList.FirstOrDefault();
                if (entity?.Status == AuditStatus.待审核)
                {
                    submitTime = entity.SubmitTime;
                    entity.AuditTime = DateTime.Now;
                    repository.Update(entity);
                }
                else throw new KnownException("当前记录不能被审核");

                var projectReviewHistory = new DP_Project_Review_History();
                projectReviewHistory.Status = status ? AuditStatus.已完成 : AuditStatus.被打回;//通过 或 打回

                if (entity.Type == ReviewType.分部工程)
                {
                    //审核通过后更新项目审核状态
                    project.Status = projectReviewHistory.Status;
                }

                asdfasdfasdf(projectReviewHistory, dto.Merge<ProjectDto, OperatorAndRemark>(), project, firstCategory, submitTime, frojectFileList.Count);
                entity.CreatorId = CurrentSession.AccountId;
                entity.CreatorName = CurrentSession.AccountName;
                CreateProjectReviewHistory(projectReviewHistory, repository);//单条
                PushProjectStatus(projectReviewHistory, firstCategory);//推送项目状态

                CreateOrUpdateOperatorHistory(dto);//创建或更新操作人
                repository.Commit();
            }
        }

        private void asdfasdfasdf(DP_Project_Review_History projectReviewHistory, OperatorAndRemark dto, DP_Project project,
            DP_Project_Category firstCategory, DateTime submitTime, int count)
        {
            projectReviewHistory.ProjectId = project.Id;
            projectReviewHistory.Name = project.Name;
            projectReviewHistory.Code = project.Code;
            projectReviewHistory.ChildCode = project.ChildCode;
            projectReviewHistory.BuilderUnitNames = project.BuilderUnitNames;
            projectReviewHistory.BuilderUnitIds = project.BuilderUnitIds;
            projectReviewHistory.FirstCategoryId = firstCategory?.Id;//分类
            projectReviewHistory.FirstCategoryName = firstCategory?.Name;
            projectReviewHistory.FileCount = count;
            projectReviewHistory.AuditId = project.AuditId;
            projectReviewHistory.AuditName = project.AuditName;
            projectReviewHistory.AuditTime = DateTime.Now;
            projectReviewHistory.SubmitTime = submitTime;//上一次提交审核时的时间
            projectReviewHistory.OperatorName = dto.OperatorName;
            projectReviewHistory.Position = dto.Position;
            projectReviewHistory.Telephone = dto.Telephone;
            projectReviewHistory.Remark = dto.Remark;
        }

        ///重审工程（重置审核状态为未上报）
        public void ResetProjectStatus(ProjectReviewHistoryDto dto, Guid firstCategoryId)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase>())
            {
                var project = repository.FindEntity<DP_Project>(dto.ProjectId);
                if (project.IsNull()) throw new KnownException("项目不存在");

                var firstCategory = repository.FindEntity<DP_Project_Category>(firstCategoryId);
                if (firstCategory.IsNull()) throw new KnownException("分类不存在");

                //通过项目Id和一级分类Id 获取最后的审核记录
                var entity = repository.IQueryable<DP_Project_Review_History>().OrderByDescending(x => x.CreatedTime).FirstOrDefault(x => x.ProjectId == dto.ProjectId && x.FirstCategoryId == firstCategoryId);

                if (entity.Status != AuditStatus.已完成 && entity.Status != AuditStatus.被打回) throw new KnownException("当前状态不能重审");
                if (entity.CreatorId != CurrentSession.AccountId) throw new KnownException("只能重审当前帐号的审核记录");

                entity.Id = Guid.NewGuid();
                entity.Status = AuditStatus.重审;
                entity.OperatorName = null;
                entity.Position = null;
                entity.Telephone = null;
                entity.CreatedTime = DateTime.Now;
                repository.Insert(entity);
            }
        }

        ///获取项目审核记录分页数据集合
        public IPagedList<ProjectReviewHistoryDto> GetProjectReviewHistoryPagedList(ProjectReviewHistoryCriteria criteria, IRepositoryBase repository = null)
        {
            if (repository == null) repository = Ioc.Resolve<IRepositoryBase>();
            using (repository)
            {
                return repository.IQueryable<DP_Project_Review_History>()
                    .WhereByKeywords(criteria?.Keywords?.Trim())
                    .WhereByFirstCategoryId(criteria.FirstCategoryId)
                    .WhereByStatus(criteria.Status)
                    .WhereByType(criteria.Type)
                    .WhereByTypeList(criteria.TypeList)
                    .WhereByAuditId(criteria.AuditId)
                    .WhereByCreatorId(criteria.CreatorId)
                    .WhereByBuilderUnitId(criteria.BuilderUnitId)
                    .WhereByProjectId(criteria.ProjectId)
                    .WhereByProjectIdList(criteria.ProjectIdList)
                    .ToDto()
                    .OrderByDescending(x => x.CreatedTime)
                    .ToPageResult1(criteria.PageIndex, criteria.PageSize);
            }
        }

        ///一级分类最后审核记录
        public Dictionary<string, ProjectReviewHistoryDto> GetProjectReviewHistoryGroupByFirstCategoryIdList(ProjectReviewHistoryCriteria criteria, IRepositoryBase repository = null)
        {
            var projectReviewHistoryList = GetProjectReviewHistoryList(criteria, repository);

            var dict = new Dictionary<string, ProjectReviewHistoryDto>();
            foreach (var item in projectReviewHistoryList)
            {
                var key = item.ProjectId + "|" + item.FirstCategoryId;
                if (!dict.ContainsKey(key))
                {
                    dict.Add(key, new ProjectReviewHistoryDto
                    {
                        Id = item.Id,
                        Name = item.Name,
                        ProjectId = item.ProjectId,
                        Code = item.Code,
                        BuilderUnitNames = item.BuilderUnitNames,
                        FirstCategoryId = item.FirstCategoryId,
                        FirstCategoryName = item.FirstCategoryName,
                        FileCount = item.FileCount,
                        AuditId = item.AuditId,
                        AuditName = item.AuditName,
                        AuditTime = item.AuditTime,
                        SubmitTime = item.SubmitTime,
                        OperatorName = item.OperatorName,
                        Position = item.Position,
                        Telephone = item.Telephone,
                        Remark = item.Remark,
                        Status = item.Status,
                        CreatedTime = item.CreatedTime,
                    });
                }
            }
            return dict;
        }

        ///获取项目审核记录
        public ProjectReviewHistoryDto GetProjectReviewHistory(Dictionary<string, ProjectReviewHistoryDto> dict, Guid firstCategoryId, Guid projectId)
        {
            var key = projectId + "|" + firstCategoryId;
            return dict.ContainsKey(key) ? dict[key] : null;
        }

        ///根据一级分类 Id 筛选审核记录
        public AuditStatus GetProjectReviewHistoryFirstCategoryId(Dictionary<string, ProjectReviewHistoryDto> dict, Guid firstCategoryId, Guid projectId)
        {
            var key = projectId + "|" + firstCategoryId;
            if (dict.ContainsKey(key))
            {
                var item = dict[key];
                return item == null ? 0 : item.Status;
            }
            return AuditStatus.未报审;//状态：1未报审，2审核中/待审核，3已打回，4已通过，5已撤回
        }

        ///计算一级分类待审核总数
        private int GetProjectReviewHistoryFirstCategoryId(Dictionary<string, ProjectReviewHistoryDto> dict, List<ProjectCategoryDto> projectCategoryList, int index, Guid projectId, AuditStatus status = AuditStatus.待审核)
        {
            var statusCount = 0;

            for (int i = 0; i < index; i++)
            {
                if (i > projectCategoryList.Count - 1) break;

                var firstCategoryId = projectCategoryList[i].Id;

                var lastStatus = GetProjectReviewHistoryFirstCategoryId(dict, firstCategoryId, projectId);
                if (lastStatus == status) ++statusCount;
            }
            return statusCount;
        }

        ///获取项目审核记录
        public IList<ProjectReviewHistoryDto> GetProjectReviewHistoryList(ProjectReviewHistoryCriteria criteria, IRepositoryBase repository = null)
        {
            if (repository == null) repository = Ioc.Resolve<IRepositoryBase>();
            using (repository)
            {
                return repository.IQueryable<DP_Project_Review_History>()
                    .WhereByKeywords(criteria?.Keywords?.Trim())
                    .WhereByProjectId(criteria.ProjectId)
                    .WhereByProjectIdList(criteria.ProjectIdList)
                    .ToDto()
                    .OrderByDescending(x => x.CreatedTime)
                    .ThenByDescending(x => x.Status).ToList();
            }
        }

        ///记录项目审核记录
        public void CreateProjectReviewHistory(DP_Project_Review_History entity, IRepositoryBase repository = null)
        {
            entity.Id = Guid.NewGuid();
            entity.CreatedTime = DateTime.Now;
            repository.Insert(entity);
        }

        #endregion

        #region 变更记录

        ///提交变更审核（工程）
        public void SubmitProjectChangeReview(ProjectChangeHistoryDto dto)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase>())
            {
                var project = repository.FindEntity<DP_Project>(dto.ProjectId);
                if (project.IsNull()) throw new KnownException("项目不存在");

                if (project.Status != AuditStatus.未报审)//只有未上报状态才能被 分解/合并
                    throw new KnownException("当前状态不允许变更");

                if (dto.Type != ChangeType.创建)
                {
                    var childCode = dto.OriginProjectCodes;
                    if (dto.Type == ChangeType.合并)
                    {
                        childCode = dto.TargetProjectCodes;
                    }

                    var f = GetProjectFirstCategoryOverview(new ProjectOverviewCriteria
                    {
                        PageIndex = 1,
                        PageSize = 1,
                        ParentId = dto.ProjectId,
                        ChildCode = childCode,
                        IsChildProject = true,
                        ChangeType = ChangeType.正常
                    }).Rows.FirstOrDefault();
                    if (!f.IsNull())
                    {
                        if (f.FirstCategoryStatus1 == AuditStatus.待审核 ||
                            f.FirstCategoryStatus2 == AuditStatus.待审核 ||
                            f.FirstCategoryStatus3 == AuditStatus.待审核 ||
                            f.FirstCategoryStatus4 == AuditStatus.待审核 ||

                            f.FirstCategoryStatus1 == AuditStatus.已完成 ||
                            f.FirstCategoryStatus2 == AuditStatus.已完成 ||
                            f.FirstCategoryStatus3 == AuditStatus.已完成 ||
                            f.FirstCategoryStatus4 == AuditStatus.已完成)
                            throw new KnownException("当前状态不允许变更");
                    }
                }

                var entity = dto.Merge<ProjectChangeHistoryDto, DP_Project_Change_History>();
                entity.Id = Guid.NewGuid();
                entity.Name = project.Name;
                entity.Code = project.Code;
                entity.AuditId = project.AuditId;
                entity.AuditName = project.AuditName;
                entity.AuditTime = DateTimeHelper.MinDateTime;
                entity.Status = AuditStatus.待审核;
                entity.SubmitTime = DateTime.Now;
                entity.CreatorId = CurrentSession.AccountId;
                entity.CreatorName = CurrentSession.AccountName;
                entity.CreatedTime = DateTime.Now;
                #region 各种单位信息赋值
                entity.ConstructionUnit = project.ConstructionUnit;
                entity.ConstructionUnitId = project.ConstructionUnitId;
                entity.BuilderUnitNames = project.BuilderUnitNames;
                entity.BuilderUnitIds = project.BuilderUnitIds;
                entity.SupervisionUnit = project.SupervisionUnit;
                entity.SupervisionUnitId = project.SupervisionUnitId;
                entity.TestingUnit = project.TestingUnit;
                entity.TestingUnitId = project.TestingUnitId;
                entity.PremixedSupplier = project.PremixedSupplier;
                entity.PremixedSupplierId = project.PremixedSupplierId;
                entity.DesignUnit = project.DesignUnit;
                entity.DesignUnitId = project.DesignUnitId;
                entity.SurveyUnit = project.SurveyUnit;
                entity.SurveyUnitId = project.SurveyUnitId;
                #endregion
                repository.Insert(entity);
                CreateOrUpdateOperatorHistory(dto);//创建或更新操作人
            }
        }

        ///撤回变更审核（工程）
        public void RecallProjectChangeReview(Guid id)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase>())
            {
                var entity = repository.FindEntity<DP_Project_Change_History>(id);
                if (entity.IsNull()) throw new KnownException("审核记录不存在");

                if (entity.Status != AuditStatus.待审核) throw new KnownException("当前状态不能撤回");
                if (entity.CreatorId != CurrentSession.AccountId) throw new KnownException("只能撤回当前帐号提交的申请");

                entity.Status = AuditStatus.已撤回;
                repository.Update(entity);
            }
        }

        ///审核变更申请（工程）
        public void ProjectChangeReview(ProjectChangeHistoryDto dto, bool status)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase>().BeginTrans())
            {
                var account = repository.FindEntity<Account>(dto.AuditId);
                if (account.IsNull()) throw new KnownException("审核帐号不存在");

                var projectChangeHistory = repository.IQueryable<DP_Project_Change_History>().FirstOrDefault(x => x.Id == dto.Id);
                if (projectChangeHistory.IsNull()) throw new KnownException("审核记录不存在");

                if (projectChangeHistory.Status != AuditStatus.待审核) throw new KnownException("当前记录不能被审核");

                var project = repository.FindEntity<DP_Project>(projectChangeHistory.ProjectId);
                if (project.IsNull()) throw new KnownException("项目不存在");
                if (dto.AuditId != project.AuditId) throw new KnownException("当前帐号不能审核该项目");

                #region 更新审核记录
                {//审核记录不应该被修改所以 这里应该修改产品设计 2018年11月18日 20:47:20
                    var oldProjectChangeHistory = repository.FindEntity<DP_Project_Change_History>(dto.Id);
                    oldProjectChangeHistory.AuditId = account.Id;
                    oldProjectChangeHistory.AuditName = account.Name;
                    oldProjectChangeHistory.AuditTime = DateTime.Now;
                    repository.Update(oldProjectChangeHistory);//更新审核记录
                    CreateOrUpdateOperatorHistory(dto);//创建或更新操作人
                }
                #endregion

                projectChangeHistory.Status = status ? AuditStatus.已完成 : AuditStatus.被打回;//通过 或 打回
                if (projectChangeHistory.Status == AuditStatus.已完成)
                {
                    if (projectChangeHistory.Type == ChangeType.创建)
                    {
                        var newProject = projectChangeHistory.Merge<DP_Project_Change_History, ProjectDto>();
                        var targetProjectName = ((JArray)JsonConvert.DeserializeObject(projectChangeHistory.TargetProjectNames)).Values().FirstOrDefault() ?? string.Empty;
                        var targetProjectTypes = ((JArray)JsonConvert.DeserializeObject(projectChangeHistory.TargetProjectTypes)).Values().ToList();
                        if (!int.TryParse(targetProjectTypes.ToString(), out var type))
                            throw new KnownException("工程类型不存在，请打回重新申请");

                        newProject.ParentId = projectChangeHistory.ProjectId;
                        newProject.Name = targetProjectName.ToString();
                        newProject.ChildCode = projectChangeHistory.TargetProjectCodes;
                        newProject.Type = type;
                        newProject.BuilderUnitIds = project.BuilderUnitIds;
                        CreateProject(newProject);
                    }
                    else if (projectChangeHistory.Type == ChangeType.分解)
                    {
                        //更新原工程信息
                        var oldProject = repository.FindEntity<DP_Project>(x => x.ParentId == project.Id && x.ChildCode == projectChangeHistory.OriginProjectCodes.Trim());
                        oldProject.ChangeType = ChangeType.分解;
                        repository.Update(oldProject);

                        var projectFileList = repository.IQueryable<DP_Project_File>().WhereByProjectId(oldProject.Id)
                            .WhereBySoftDeletedStatus(SoftDeletedStatus.正常).ToList();

                        //创建新工程信息
                        var targetProjectCodes = projectChangeHistory.TargetProjectCodes.Split(',');
                        var targetProjectNames = ((JArray)JsonConvert.DeserializeObject(projectChangeHistory.TargetProjectNames)).Values().ToList();
                        var targetProjectTypes = ((JArray)JsonConvert.DeserializeObject(projectChangeHistory.TargetProjectTypes)).Values().ToList();
                        var date = DateTime.Now;
                        for (int i = 0; i < targetProjectCodes.Length; i++)
                        {
                            var childCode = targetProjectCodes[i];
                            var newProject = Merge(project, childCode);
                            newProject.Name = !string.IsNullOrWhiteSpace(targetProjectNames[i].ToString()) ? targetProjectNames[i].ToString() : project.Name;
                            if (!int.TryParse(targetProjectTypes[i].ToString(), out var type))
                                throw new KnownException("工程类型不存在，请打回重新申请");
                            newProject.Type = type;
                            newProject.CreatedTime = date.AddSeconds(1);
                            repository.Insert(newProject);

                            //将已有的文件【复制】到新工程下
                            foreach (var item in projectFileList)
                            {
                                var file = new DP_Project_File
                                {
                                    Id = Guid.NewGuid(),
                                    ShortName = item.ShortName,
                                    Name = item.Name,
                                    Path = item.Path,
                                    Size = item.Size,
                                    Extension = item.Extension,
                                    FileId = item.FileId,
                                    UploadTime = item.UploadTime,
                                    SoftDeleted = item.SoftDeleted,
                                    Status = item.Status,
                                    FirstCategoryId = item.FirstCategoryId,
                                    SecondCategoryId = item.SecondCategoryId,
                                    ThreeCategoryId = item.ThreeCategoryId,
                                    ProjectId = newProject.Id,
                                    CreatedTime = item.CreatedTime
                                };
                                repository.Insert(file);
                            }
                        }
                    }
                    else if (projectChangeHistory.Type == ChangeType.合并)
                    {
                        //更新原工程信息
                        var codeList = projectChangeHistory.OriginProjectCodes.Split(',').ToList();
                        var oldProjectList = repository.IQueryable<DP_Project>().WhereByParentId(project.Id).WhereByChildCodeList(codeList).ToList();
                        foreach (var item in oldProjectList)
                        {
                            item.ChangeType = ChangeType.合并;
                            repository.Update(item);
                        }
                        //创建新工程
                        var newProject = Merge(project, projectChangeHistory.TargetProjectCodes);
                        newProject.Name = ((JArray)JsonConvert.DeserializeObject(projectChangeHistory.TargetProjectNames)).Values().FirstOrDefault().ToString();
                        repository.Insert(newProject);

                        //将已有的文件【合并】到新工程下
                        var projectFileList = repository.IQueryable<DP_Project_File>().WhereByProjectIdList(oldProjectList.Select(x => x.Id).ToList())
                            .WhereBySoftDeletedStatus(SoftDeletedStatus.正常).ToList();
                        foreach (var item in projectFileList)
                        {
                            item.Id = Guid.NewGuid();
                            item.ProjectId = newProject.Id;
                            repository.Insert(item);
                        }
                    }
                }

                projectChangeHistory.Id = Guid.NewGuid();
                projectChangeHistory.AuditId = account.Id;
                projectChangeHistory.AuditName = account.Name;
                projectChangeHistory.AuditTime = DateTime.Now;
                projectChangeHistory.Remark = dto.Remark;
                projectChangeHistory.CreatedTime = DateTime.Now;
                repository.Insert(projectChangeHistory);//创建新的审核记录

                repository.Commit();
            }
        }

        ///使用新的项目实体
        public DP_Project Merge(DP_Project entity, string childCode)
        {
            return new DP_Project
            {
                Id = Guid.NewGuid(),
                Name = entity.Name,
                ParentId = entity.Id,
                Code = entity.Code,
                ChildCode = childCode,
                Area = entity.Area,
                AreaId = entity.AreaId,
                AuditId = entity.AuditId,
                AuditName = entity.AuditName,
                AuditTime = entity.AuditTime,
                IsBIM = entity.IsBIM,
                Status = entity.Status,
                Address = entity.Address,
                Location = entity.Location,
                Image = entity.Image,
                ImageUploadTime = entity.ImageUploadTime,
                ChangeType = ChangeType.正常,

                ConstructionUnit = entity.ConstructionUnit,
                ConstructionUnitId = entity.ConstructionUnitId,
                BuilderUnitNames = entity.BuilderUnitNames,
                BuilderUnitIds = entity.BuilderUnitIds,
                SupervisionUnit = entity.SupervisionUnit,
                SupervisionUnitId = entity.SupervisionUnitId,
                TestingUnit = entity.TestingUnit,
                TestingUnitId = entity.TestingUnitId,
                PremixedSupplier = entity.PremixedSupplier,
                PremixedSupplierId = entity.PremixedSupplierId,
                DesignUnit = entity.DesignUnit,
                DesignUnitId = entity.DesignUnitId,
                SurveyUnit = entity.SurveyUnit,
                SurveyUnitId = entity.SurveyUnitId,

                CreatedTime = DateTime.Now,
            };
        }

        private IPagedList<ProjectChangeHistoryDto> QueryProjectChangeHistoryPagedList(ProjectChangeHistoryCriteria criteria, int orderType, IRepositoryBase repository)
        {
            var query = repository.IQueryable<DP_Project_Change_History>()
                .WhereByKeywords(criteria?.Keywords?.Trim())
                .WhereByStatus(criteria.Status)
                .WhereByStatusList(criteria.StatusList)
                .WhereByType(criteria.Type)
                .WhereByAuditId(criteria.AuditId)
                .WhereByBuilderUnitId(criteria.BuilderUnitId)
                .WhereByProjectId(criteria.ProjectId)
                .WhereByProjectIdList(criteria.ProjectIdList)
                .WhereBySubmitTimeList(criteria.SubmitTimeList)
                .WhereBySubmitTimeNotInList(criteria.SubmitTimeNotInList)
                .WhereByAuditTimeList(criteria.AuditTimeList)
                .ToDto();

            if (orderType == 1) return query.OrderBy(x => x.SubmitTime)
                .ThenByDescending(x => x.CreatedTime)
                .ToPageResult1(criteria.PageIndex, criteria.PageSize);

            return query.OrderByDescending(x => x.SubmitTime)
                 .ThenByDescending(x => x.CreatedTime)
                 .ToPageResult1(criteria.PageIndex, criteria.PageSize);
        }

        ///获取项目变更记录（待审核放在前面）-分页数据集合
        public Tuple<int, IPagedList<ProjectChangeHistoryDto>> GetProjectChangeHistorySubmitTimePagedList(ProjectChangeHistoryCriteria criteria, IRepositoryBase repository = null)
        {
            if (repository == null) repository = Ioc.Resolve<IRepositoryBase>();
            using (repository)
            {//列表最前面显示待审核数据，当待审核数据不够一页时，再从数据库中抽取补满一页
             //1.获取已审核信息，下面再把已审核的这部分排除
                criteria.SubmitTimeNotInList = repository.IQueryable<DP_Project_Change_History>()
                    .WhereByAuditId(criteria.AuditId)
                    .WhereByProjectId(criteria.ProjectId)
                    .WhereByBuilderUnitId(criteria.BuilderUnitId)
                    .WhereByStatusList(new List<AuditStatus>() { AuditStatus.已完成, AuditStatus.被打回, AuditStatus.已撤回 })
                    .OrderByDescending(x => x.SubmitTime)
                    .ThenByDescending(x => x.CreatedTime)
                    .Take(criteria.PageSize * 10)
                    .Select(x => x.SubmitTime).ToList();

                //2.获取待审核数据（排除已审核的变更记录）
                var needReviewList = QueryProjectChangeHistoryPagedList(criteria, 1, repository);

                //3.获取原始数据
                criteria.SubmitTimeNotInList = null;
                if (criteria.PageIndex > 1 && needReviewList.Rows.Count > 0) criteria.PageIndex -= 1;
                var result = QueryProjectChangeHistoryPagedList(criteria, 2, repository);

                //4.首先排除已获取的待审数据
                var indexList = new List<ProjectChangeHistoryDto>();
                for (int i = 0; i < result.Rows.Count; i++)
                {
                    var item = result.Rows[i];
                    if (needReviewList.Rows.Any(x => x.Id == item.Id))
                        indexList.Add(item);
                }
                foreach (var item in indexList)
                {
                    result.Rows.Remove(item);
                }

                //5.将待审数据加入集合
                for (int i = 0; i < needReviewList.Rows.Count; i++)
                {
                    result.Rows.Insert(0, needReviewList.Rows[needReviewList.Rows.Count - 1 - i]);
                }

                //6.移除超出 PageSize 的项
                indexList.Clear();
                for (int i = 0; i < result.Rows.Count - criteria.PageSize; i++)
                {
                    var item = result.Rows[result.Rows.Count - 1 - i];
                    indexList.Add(item);
                }
                foreach (var item in indexList)
                {
                    result.Rows.Remove(item);
                }

                #region 7.更新待审核数据中，已经被审核的审核信息，在页面上就不会再显示审核操作
                if (result.Rows.Count != 0)
                {
                    var submitTimeList = result.Rows.Where(x => x.Status == AuditStatus.待审核 || x.Status == AuditStatus.已撤回).Select(x => x.SubmitTime).ToList();
                    criteria = new ProjectChangeHistoryCriteria
                    {
                        SubmitTimeList = submitTimeList,
                        StatusList = new List<AuditStatus> { AuditStatus.被打回, AuditStatus.已完成, AuditStatus.已撤回 },
                        PageIndex = 1,
                        PageSize = 100,
                    };
                    var submitResult = QueryProjectChangeHistoryPagedList(criteria, 2, repository);

                    foreach (var item in result.Rows)
                    {
                        if (item.Status < AuditStatus.待审核) continue;

                        //出现过已打回或已完成，更新上一次待审核记录审核时间赋值，通过审核时间找到
                        var lastSubmitHistory = submitResult.Rows.FirstOrDefault(x => x.SubmitTime == item.SubmitTime);
                        if (lastSubmitHistory != null)
                        {
                            item.AuditId = lastSubmitHistory.AuditId;
                            item.AuditName = lastSubmitHistory.AuditName;
                            item.AuditTime = lastSubmitHistory.AuditTime;
                        }
                    }
                }
                #endregion

                return new Tuple<int, IPagedList<ProjectChangeHistoryDto>>(needReviewList.TotalCount, result);
            }
        }

        #endregion

        #region 单项申报记录

        ///创建或更新单项申报
        public Guid CreateOrUpdateSubitemReview(SubitemReviewDto dto)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase>())
            {
                var project = repository.FindEntity<DP_Project>(dto.ProjectId);
                if (project.IsNull()) throw new KnownException("项目不存在");

                var entity = dto.Merge<SubitemReviewDto, SubitemReview>();
                if (entity.Id == Guid.Empty)
                {
                    entity.Id = Guid.NewGuid();
                    entity.Name = project.Name;
                    entity.Code = project.Code;
                    entity.BuilderUnitIds = project.BuilderUnitIds;
                    entity.BuilderUnitNames = project.BuilderUnitNames;
                    entity.AuditId = project.AuditId;//审核人信息与项目一致
                    entity.AuditName = project.AuditName;
                    entity.Status = AuditStatus.待审核;
                    entity.CreatorId = CurrentSession.AccountId;
                    entity.CreatorName = CurrentSession.AccountName;
                    entity.CreatedTime = DateTime.Now;
                    entity.SubmitTime = DateTime.Now;
                    repository.Insert(entity);
                }
                else
                {
                    entity = repository.IQueryable<SubitemReview>().FirstOrDefault(x => x.Id == dto.Id);
                    entity.Path = dto.Path;
                    entity.FileId = dto.FileId;
                    repository.Update(entity);
                }

                CreateSubitemReviewHistory(entity.Merge<SubitemReview, SubitemReviewHistory>(), entity.Status, repository);//创建单项申报记录

                return entity.Id;
            }
        }

        private void CreateSubitemReviewHistory(SubitemReviewHistory entity, AuditStatus status, IRepositoryBase repository)
        {
            entity.Id = Guid.NewGuid();
            entity.Status = status;
            entity.CreatedTime = DateTime.Now;
            entity.SubmitTime = DateTime.Now;
            repository.Insert(entity);
        }

        ///撤回单项申报审核记录
        public void RecallSubitemReviewHistory(SubitemReviewHistoryDto dto)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase>())
            {
                var entity = repository.IQueryable<SubitemReviewHistory>().FirstOrDefault(x => x.Id == dto.Id);
                entity.Status = AuditStatus.未报审;
                entity.SubmitTime = DateTimeHelper.MinDateTime;
                repository.Update(entity);

                CreateSubitemReviewHistory(entity, AuditStatus.已撤回, repository);//创建单项申报记录
            }
        }

        ///审核单项申报审核记录
        public void ReviewSubitemReviewHistory(SubitemReviewHistoryDto dto)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase>())
            {
                var entity = repository.IQueryable<SubitemReviewHistory>().FirstOrDefault(x => x.Id == dto.Id);
                entity.Status = dto.Status;
                entity.AuditTime = DateTime.Now;
                repository.Update(entity);

                CreateSubitemReviewHistory(entity, dto.Status, repository);//创建单项申报记录
            }
        }

        ///重审单项申报审核记录
        public void ResetSubitemReviewHistory(SubitemReviewHistoryDto dto)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase>())
            {
                if (CurrentSession.Type != AccountType.区县帐号) throw new KnownException("当前用户没有重审权限，请联系管理员");
                var entity = repository.IQueryable<SubitemReviewHistory>().FirstOrDefault(x => x.Id == dto.Id);
                entity.Status = AuditStatus.未报审;
                entity.SubmitTime = DateTimeHelper.MinDateTime;
                repository.Update(entity);

                CreateSubitemReviewHistory(entity, AuditStatus.重审, repository);//创建单项申报记录
            }
        }

        ///获取单项申报审核-分页数据集合
        public IPagedList<SubitemReviewDto> GetSubitemReviewPagedList(SubitemReviewHistoryCriteria criteria)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase>())
            {
                return repository.IQueryable<SubitemReview>()
                .WhereByKeywords(criteria?.Keywords?.Trim())
                .WhereByStatus(criteria.Status)
                .WhereByType(criteria.Type)
                .WhereByAuditId(criteria.AuditId)
                .WhereByApplyForUnitId(criteria.ApplyForUnitId)
                .WhereByProjectId(criteria.ProjectId)
                .WhereByProjectIdList(criteria.ProjectIdList)
                .ToDto()
                .OrderByDescending(x => x.CreatedTime)
                .ToPageResult1(criteria.PageIndex, criteria.PageSize);
            }
        }

        ///获取单项申报审核记录-分页数据集合
        public IPagedList<SubitemReviewHistoryDto> GetSubitemReviewHistoryPagedList(SubitemReviewHistoryCriteria criteria)
        {
            using (var repository = Ioc.Resolve<IRepositoryBase>())
            {
                return repository.IQueryable<SubitemReviewHistory>()
                .WhereByKeywords(criteria?.Keywords?.Trim())
                .WhereByStatus(criteria.Status)
                .WhereByType(criteria.Type)
                .WhereByAuditId(criteria.AuditId)
                .WhereByApplyForUnitId(criteria.ApplyForUnitId)
                .WhereByProjectId(criteria.ProjectId)
                .ToDto()
                .OrderByDescending(x => x.CreatedTime)
                .ToPageResult1(criteria.PageIndex, criteria.PageSize);
            }
        }

        #endregion

        #region 操作人记录相关

        private void CreateOrUpdateOperatorHistory(OperatorSystemEntity entity)
        {
            CreateOrUpdateOperatorHistory(entity.OperatorName, entity.Position, entity.Telephone);
        }

        private void CreateOrUpdateOperatorHistory(OperatorEntityBase entity)
        {
            CreateOrUpdateOperatorHistory(entity.OperatorName, entity.Position, entity.Telephone);
        }

        ///创建或更新操作人
        private void CreateOrUpdateOperatorHistory(string name, string position, string telephone)
        {
            var thread = new Thread(() =>
            {
                try
                {
                    using (var repository = Ioc.Resolve<IRepositoryBase>())
                    {
                        var entity = repository.FindEntity<OperatorInfo>(CurrentSession.AccountId);

                        if (entity.IsNull())
                        {
                            entity = new OperatorInfo
                            {
                                Id = CurrentSession.AccountId,
                                OperatorName = name,
                                Position = position,
                                Telephone = telephone,
                                CreatedTime = DateTime.Now,
                            };
                            repository.Insert(entity);
                        }
                        else if (entity.OperatorName != name || entity.Position != position || entity.Telephone != telephone)
                        {
                            entity.OperatorName = name;
                            entity.Position = position;
                            entity.Telephone = telephone;
                            entity.ModifiedTime = DateTime.Now;
                            repository.Update(entity);
                        }
                    }
                }
                catch (Exception)
                {

                }
            })
            { IsBackground = true };
            thread.Start();
        }

        ///根据用户Id获取操作人信息
        public OperatorInfoDto GetOperatorInfoByAccountId()
        {
            using (var repository = Ioc.Resolve<IRepositoryBase>())
            {
                var entity = repository.FindEntity<OperatorInfo>(CurrentSession.AccountId);
                return entity.Merge<OperatorInfo, OperatorInfoDto>();
            }
        }

        #endregion

        #region 数据推送

        /// <summary>
        /// 推送项目文件
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="firstCategory">一级分类</param>
        /// <param name="secondCategory">二级分类</param>
        /// <param name="threeCategoryName">表号</param>
        /// <param name="fourCategoryName">表格名称</param>
        private void PushProjectFile(DP_Project_File entity, ProjectCategoryDto firstCategory, ProjectCategoryDto secondCategory, string threeCategoryName, string fourCategoryName)
        {
            var thread = new Thread(() =>
            {
                var code = GetProjectById(entity.ProjectId).Code;
                new ProjectUploadFileHandle().Handler(new ProjectUploadFileEvent
                {
                    projectCode = code,
                    partCode = GetCodeByCategory(firstCategory.Level, firstCategory.Sort),
                    docTypeCode = GetCodeByCategory(secondCategory.Level, secondCategory.Sort),
                    docNo = threeCategoryName,
                    docName = fourCategoryName,
                    fileUrl = entity.Path,
                    recordTime = entity.CreatedTime,
                    sourceId = entity.Id.ToString()
                });
            })
            { IsBackground = true };
            thread.Start();
        }

        ///推送项目状态
        private void PushProjectStatus(DP_Project_Review_History entity, DP_Project_Category firstCategory)
        {
            var thread = new Thread(() =>
            {
                new ProjectStatusChangeHandle().Handler(new ProjectStatusChangeEvent
                {
                    projectCode = entity.Code,
                    partCode = GetCodeByCategory(firstCategory.Level, firstCategory.Sort),
                    status = entity.Status.GetHashCode().ToString()
                });
            })
            { IsBackground = true };
            thread.Start();
        }

        /// <summary>
        /// 通过子级编号返回千变科技需要的 Code
        /// </summary>
        /// <param name="level">子级编号</param>
        /// <param name="sort">序号</param>
        /// <returns></returns>
        public string GetCodeByCategory(int level, int sort)
        {
            var prefix = "P";
            if (level == 2) prefix = "DT";
            return prefix + (sort.ToString().PadLeft(3, '0'));
        }
        #endregion
    }
}
